/*
 * SubSonic - http://subsonicproject.com
 * 
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an 
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
*/

using System;
using System.Data;

namespace SubSonic
{
    /// <summary>
    /// Summary for the ActiveList&lt;ItemType, ListType&gt; class
    /// </summary>
    /// <typeparam name="ItemType">The type of the tem type.</typeparam>
    /// <typeparam name="ListType">The type of the ist type.</typeparam>
    [Serializable]
    public class ActiveList<ItemType, ListType> : AbstractList<ItemType, ListType>
        where ItemType : ActiveRecord<ItemType>, new()
        where ListType : AbstractList<ItemType, ListType>, new()
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ActiveList&lt;ItemType, ListType&gt;"/> class.
        /// </summary>
        public ActiveList() {}

        /// <summary>
        /// Creates and loads the collection, leaving the IDataReader open.
        /// </summary>
        /// <param name="rdr"></param>
        public ActiveList(IDataReader rdr)
        {
            Load(rdr);
        }

        /// <summary>
        /// Creates and loads the collection, with option to set IDataReader close behavior.
        /// </summary>
        /// <param name="rdr"></param>
        /// <param name="closeReader"></param>
        public ActiveList(IDataReader rdr, bool closeReader)
        {
            Load(rdr);
            if(closeReader)
                rdr.Close();
        }

        /// <summary>
        /// Finds the specified primary key value.
        /// </summary>
        /// <param name="primaryKeyValue">The primary key value.</param>
        /// <returns></returns>
        public ActiveRecord<ItemType> Find(object primaryKeyValue)
        {
            ActiveRecord<ItemType> result = null;
            foreach(ItemType item in this)
            {
                if (item.GetPrimaryKeyValue().Equals(primaryKeyValue))
                {
                    result = item;
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// Saves all the records in a collection to the DB
        /// </summary>
        public void SaveAll(string userName)
        {
            foreach(ItemType item in this)
                item.Save(userName);
        }

        /// <summary>
        /// Saves all the records in a collection to the DB
        /// </summary>
        public void SaveAll(Guid userID)
        {
            foreach(ItemType item in this)
                item.Save(userID);
        }
        
        /// <summary>
        /// Uses a transaction to quickly saves all the records in a collection to the DB
        /// The primary keys of any new records are not updated in the collection
        /// You must reload the collection to get the latest data
        /// </summary>
        public void BatchSave(string userName)
        {
            QueryCommandCollection commands = new QueryCommandCollection();
            foreach(ItemType item in this)
            {
                QueryCommand cmd = item.GetSaveCommand(userName);
                if(cmd != null)
                    commands.Add(cmd);
            }

            DataService.ExecuteTransaction(commands);
        }

        /// <summary>
        /// Batches the save.
        /// </summary>
        public void BatchSave()
        {
            BatchSave(string.Empty);
        }

        /// <summary>
        /// Batches the save.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        public void BatchSave(Guid userID)
        {
            BatchSave(userID.ToString());
        }

        /// <summary>
        /// Batches the save.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        public void BatchSave(int userID)
        {
            BatchSave(userID.ToString());
        }

        /// <summary>
        /// Saves all the records in a collection to the DB
        /// </summary>
        public void SaveAll(int userId)
        {
            foreach(ItemType item in this)
                item.Save(userId);
        }
    }
}